import java.util.Properties;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import javax.mail.Session;
import javax.mail.Store;

/* Test IMAP Connectivity for following ports: 
 * 		port 143 : normal IMAP (through aol)
 * 		port 993 : IMAPS (through gmail)
 * 
 *	Usage for this class is as follows: 
 * 		1) Create new class
 * 		2) Call setProperties(int port)
 * 		3) call runtests (int numberOfTests)
 */
public class AllIMAPConnectivity implements Runnable {
	
	ConnectionStatus internetStatus = new ConnectionStatus();
	
	private String HOST_NAME;
	private int HOST_PORT;
	private String AUTH_USER;
	private String AUTH_PWD;
	private String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
								 
	private Properties props = new Properties();	
	
	private boolean badFlag = true; // used for the case that the user provides a bad port
	
	// for thread synchronization
	ResultsTable sharedTable = new ResultsTable();
	private int numTests;
	static CyclicBarrier barrier;
	
	private String IMAP_KEY;
	
	
	public AllIMAPConnectivity(ResultsTable r, CyclicBarrier b, int n){
		sharedTable = r;
		barrier = b;
		numTests = n;
	}
	
	
	@Override
	public void run() {
		try {
			internetStatus = runTests(numTests);
		} catch (Exception e) {
		}
		sharedTable.addResult(IMAP_KEY, internetStatus);
		try {
			barrier.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	public void setProperties(int port) {
		if (port == 143) {
			IMAP_KEY = "imap";
			badFlag = false;
			HOST_NAME = "imap.aol.com";
			AUTH_USER = "mifcais@aol.com";
			HOST_PORT = 143;
			AUTH_PWD = "COMSE6181";			
//			props = System.getProperties();		
		    props.put("mail.imap.host", HOST_NAME);
		    props.put("mail.imap.port", "143");
		    props.put("mail.imap.auth", "true");
			props.put("mail.store.protocol", "imap");						
						
		} else if (port == 993) {
			IMAP_KEY = "imaps";
			badFlag = false;
			HOST_NAME = "imap.gmail.com";
			HOST_PORT = 993;
			AUTH_USER = "mifcais2@gmail.com";
			AUTH_PWD = "COMSE6181";			
//			props = System.getProperties();
		    props.put("mail.imaps.host", HOST_NAME);
		    props.put("mail.imaps.port", "993");
		    props.put("mail.imaps.auth", "true");
			props.put("mail.store.protocol", "imaps");	
			props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
			props.setProperty("mail.imap.socketFactory.fallback", "false");
			props.setProperty("mail.imap.socketFactory.port", "993");							        
	        
		} else {
			System.out.println("You have provided a bad port");
			badFlag = true;
		}
	}
				
	public ConnectionStatus runTests (int n) {
		System.out.println("In IMAP RUN for port " + HOST_PORT);
		
			for (int i = 0; i < n; i++){
				// run the test n times
				if (isConnected() && !badFlag) {
					this.internetStatus.addPassedAttempt();
				} else {
					this.internetStatus.addFailedAttempt();
				}
			}			
			return this.internetStatus;
	
	}
	
    private boolean isConnected(){    	
    	
    	boolean result = false; // initialize result as false    	
    	if (! (HOST_PORT == 143 || HOST_PORT == 993) )
    		return result;
    	
    	Session mailSession = Session.getDefaultInstance(props,null);
    	mailSession.setDebug(false);    	
    	Store store;
    	
    	try {
	    	if (HOST_PORT == 993) {
	    		store = mailSession.getStore("imaps");
	    	} else { // HOST_PORT = 143
	    		store = mailSession.getStore("imap");
	    	}
	    	
	    	if (!store.isConnected())
	    		store.connect(HOST_NAME, AUTH_USER, AUTH_PWD);
	    	else
	    		System.out.println("Already Connected");
	    	store.close();
	    	result = true;
    	} catch (Exception e) {
    		return false;
    	}
    	
    	return result;
    }
}